package com.ruoyi.auth.service.impl;

import cn.hutool.core.util.StrUtil;
import com.ruoyi.auth.dto.EcUser;
import com.ruoyi.auth.service.EcUserService;
import com.ruoyi.common.core.enums.HttpResponseEnum;
import com.ruoyi.common.core.exception.base.BaseException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.query.LdapQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.naming.ldap.Rdn;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class EcUserServiceImpl implements EcUserService {

    private static final String ATTR_OBJ_CLASS = "objectClass";

    private static final String USER = "user";

    @Autowired
    private LdapTemplate ldapTemplate;

    /**
     * 获取所有用户信息
     *
     * @return
     */
    @Override
    public List<EcUser> getAllUser() {
        List<EcUser> list = ldapTemplate.find(LdapQueryBuilder.query().base("OU=managedby").where(ATTR_OBJ_CLASS).is(USER), EcUser.class);
        if (CollectionUtils.isEmpty(list)) {
            return Collections.emptyList();
        }
        // 只需ou在Domain Users和EC的用户
        return list.stream().filter(e -> {
            List<Rdn> rdns = e.getLdapName().getRdns();
            return rdns.stream().anyMatch(p -> p.getType().equals("OU") && (p.getValue().equals("EC") || p.getValue().equals("Contractors")));
        }).collect(Collectors.toList());
    }

    /**
     * 根据域账号查询用户信息
     *
     * @param userAccount
     * @return
     */
    @Override
    public EcUser getUserByAccount(String userAccount) {
        return ldapTemplate.find(LdapQueryBuilder.query().where(ATTR_OBJ_CLASS).is(USER).and("sAMAccountName").is(userAccount), EcUser.class).stream().findFirst().orElse(null);
    }

    @Override
    public Boolean authUser(String userAccount, String password) {
        if (StrUtil.isBlankIfStr(password) || StrUtil.isBlankIfStr(userAccount)) {
            return Boolean.FALSE;
        }
        try {
            ldapTemplate.authenticate(LdapQueryBuilder.query().where(ATTR_OBJ_CLASS).is(USER).and("sAMAccountName").is(userAccount), password);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BaseException(HttpResponseEnum.USERS_LDAP_FAILED.getMsg());
        }
        return Boolean.TRUE;
    }

}
